import { MEMBER_LEVEL_MAP } from 'sub/assets/constant/view-constants';
import { ComponentWithComputed } from 'miniprogram-computed';

ComponentWithComputed({
  properties: {
    /** 当前swiper-item的索引 */
    currentSwiperIndex: Number,
    /** 当前等级索引 */
    currentLevel: Number,
  },
  data: {
    /** 各等级内容列表 */
    memberLevelList: Array.from(MEMBER_LEVEL_MAP).map((item) => {
      return item[1];
    }),
    /** 总等级数 */
    totalLevel: Array.from(MEMBER_LEVEL_MAP).length,
    /** swiper-item的宽度 */
    swiperItemWidth: 0,
    /** swiper-item的高度 */
    swiperItemHeight: 0,
    /** swiper-item的间距 */
    swiperItemMargin: 50,
    /** swiper在X轴的偏移量 */
    swiperTranslateX: 0,
    /** 基础偏移量 */
    baseTranslateX: 88,
    /** 是否在触摸 */
    isTouch: false,
    /** 初始触摸横坐标 */
    initialTouchX: 0,
    /** 开始触摸时的偏移量 */
    initialTranslateX: 0,
  },
  computed: {
    swiperContainerStyle(data) {
      return `
      height: ${data.swiperItemHeight}px;
      padding-left: ${data.baseTranslateX}px;
      `;
    },
    swiperStyle(data) {
      return `
      grid-template-columns: repeat(${data.totalLevel}, 214px);
      column-gap: ${data.swiperItemMargin}px;
      transform: translateX(${data.swiperTranslateX}px);
      ${
        data.isTouch
          ? 'transition: none;'
          : 'transition: transform 0.1s ease-in-out;'
      }
      `;
    },
    swiperItemList(data) {
      const realSwiperItemCount = 5;
      if (data.currentSwiperIndex <= Math.floor(realSwiperItemCount / 2)) {
        return data.memberLevelList
          .slice(0, realSwiperItemCount)
          .map((item, index) => {
            return {
              ...item,
              swiperItemIndex: index,
            };
          });
      }

      if (
        data.currentSwiperIndex >=
        data.totalLevel - Math.floor(realSwiperItemCount / 2)
      ) {
        return data.memberLevelList
          .slice(data.totalLevel - realSwiperItemCount)
          .map((item, index) => {
            return {
              ...item,
              swiperItemIndex: data.totalLevel - realSwiperItemCount + index,
            };
          });
      }

      return data.memberLevelList
        .slice(
          data.currentSwiperIndex - Math.floor(realSwiperItemCount / 2),
          data.currentSwiperIndex + Math.floor(realSwiperItemCount / 2) + 1,
        )
        .map((item, index) => {
          return {
            ...item,
            swiperItemIndex:
              data.currentSwiperIndex -
              Math.floor(realSwiperItemCount / 2) +
              index,
          };
        });
    },
  },
  lifetimes: {
    attached() {
      this.init();
    },
  },
  methods: {
    /**
     * 获取并返回单个swiper-item的宽度和高度
     * @return  swiper-item的宽度和高度
     */
    getSwiperItemWidth(): Promise<{
      width: number;
      height: number;
    }> {
      const query = this.createSelectorQuery();
      query.select('.swiper-item').boundingClientRect();
      return new Promise((resolve) => {
        query.exec((res) => {
          resolve({
            width: res[0].width,
            height: res[0].height,
          });
        });
      });
    },
    /** 计算并并返回初始偏移量，让swiper-item在swiper-container内居中 */
    async getInitialTranslateX(): Promise<number> {
      const query = this.createSelectorQuery();
      query.select('.swiper-container').boundingClientRect();
      const { width } = await this.getSwiperItemWidth();
      return new Promise((resolve) => {
        query.exec((res) => {
          resolve((res[0].width - width) / 2);
        });
      });
    },
    /** 初始化
     * 1. 获取swiper-item的宽度和高度
     * 2. 设置基础偏移量
     * 3. 如果有传入currentSwiperIndex，则将对应的swiper-item移动到中间
     */
    async init() {
      const { width, height } = await this.getSwiperItemWidth();
      const baseTranslateX = await this.getInitialTranslateX();
      this.setData({
        swiperItemWidth: width,
        swiperItemHeight: height,
        baseTranslateX,
      });
      if (this.data.currentSwiperIndex) {
        this.moveSwiper(this.data.currentSwiperIndex);
      }
    },
    /**
     * 移动swiper将对应的索引的swiper-item移动到中间
     * @param index 索引
     */
    moveSwiper(index: number) {
      const { swiperItemWidth, swiperItemMargin } = this.data;
      const swiperTranslateX = -index * (swiperItemWidth + swiperItemMargin);
      this.setData({
        swiperTranslateX,
        currentSwiperIndex: index,
      });
    },
    /**
     * swiper-item的touchstart事件
     * @param e 事件对象
     */
    swiperItemTouchStart(e: WechatMiniprogram.TouchEvent) {
      const { clientX } = e.touches[0];
      this.setData({
        isTouch: true,
        initialTouchX: clientX,
        initialTranslateX: this.data.swiperTranslateX,
      });
    },
    /**
     * swiper-item的touchmove事件
     * @param e 事件对象
     */
    swiperItemTouchMove(e: WechatMiniprogram.TouchEvent) {
      const { clientX } = e.touches[0];
      const swiperTranslateX =
        this.data.initialTranslateX + clientX - this.data.initialTouchX;
      this.setData({
        swiperTranslateX,
      });
    },
    /**
     * swiper-item的touchend事件
     * @param e 事件对象
     */
    swiperItemTouchEnd(e: WechatMiniprogram.TouchEvent) {
      // 计算当前swiper-item的索引
      const { swiperItemWidth, swiperItemMargin, swiperTranslateX } = this.data;
      const index = Math.round(
        -swiperTranslateX / (swiperItemWidth + swiperItemMargin),
      );
      this.setData({
        isTouch: false,
      });
      this.moveSwiper(index < 0 ? 0 : index > 17 ? 17 : index);
    },
  },
});
